// 1. C语言不定参宏函数

// #include <stdio.h>

// // 当可变参数为空时，##会消除前面的逗号，避免语法错误
// #define Print_1(fmt, ...) printf("[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)

// int main()
// {
//     Print_1();
//     Print_1("%s","Hello Log");
//     return 0;
// }

// 2. C语言不定参函数

// #include <iostream>
// #include <stdarg.h>

// void PrintNum(int n, ...)
// {
//     va_list ap;
//     va_start(ap, n);

//     for(int i = 0; i < n; ++i)
//     {
//         int num = va_arg(ap, int); // 拿到一个int类型的值
//         std::cout << num << std::endl;
//     }

//     va_end(ap);
// }

// void Print_2(const char* fmt, ...)
// {
//     va_list ap;
//     va_start(ap, fmt);

//     char* str;
//     vasprintf(&str, fmt, ap);
//     std::cout << str << std::endl;

//     va_end(ap);
//     free(str);
// }

// int main()
// {
//     PrintNum(3, 1, 2, 3);
//     Print_2("%s\n", "Hello Log");
//     return 0;
// }

// 3. C++不定参函数

#include <iostream>

void Print_3()
{
    // 编译时递归的终止条件，参数包是0个时，直接匹配这个函数。
    std::cout << "end" << std::endl;
}

template<typename T, typename ...Args>
void Print_3(const T& val, Args&& ...args)
{
    std::cout << val << std::endl;
    Print_3(std::forward<Args>(args)...); // 保留原始实参的 “左值 / 右值身份”
}

int main()
{
    Print_3();
    Print_3(1, 2, 3, "Hello Log");
    return 0;
}